package view;

import java.awt.Color;
import java.awt.Dimension;
import java.awt.Graphics;
import java.util.ArrayList;
import java.util.List;
import java.util.ListIterator;
import java.util.Random;

import javax.swing.BorderFactory;
import javax.swing.JComponent;
import javax.swing.border.BevelBorder;

import Environment.*;

import individual.MovingEntity;

/**
 * Creates a Canvas view that contains an Environment. It basically
 * acts as a controller for the Environment. 
 * @author Ga-Young Joung and Perry Zheng
 *
 */
public class Canvas extends JComponent {
	private Random myGenerator;
	private Environment myEnvironment;

	/**
	 * Create a Canvas with the given size.
	 * 
	 * @param size  width and height of canvas in pixels
	 */
	public Canvas(Dimension size) {
		setBorder(BorderFactory.createBevelBorder(BevelBorder.LOWERED));
		myGenerator = new Random();
		myEnvironment = new Environment(this);
		myEnvironment.setBoundary(new WallBoundary(myEnvironment));
	}

	/**
	 * Gets the environment
	 * @return The environment which the Canvas is controlling
	 */
	public Environment getEnvironment() {
		return myEnvironment;
	}

	/**
	 * Paint the contents of the canvas.
	 * 
	 * Never called by you directly, instead called by Java runtime when area of
	 * screen covered by this container needs to be displayed (i.e., creation,
	 * uncovering, change in status)
	 * 
	 * @param pen  used to paint shape on the screen
	 */
	public void paintComponent(Graphics pen) {
		pen.setColor(Color.WHITE);
		pen.fillRect(0, 0, getSize().width, getSize().height);
		List<MovingEntity> allIndividuals = myEnvironment.getIndividuals();
		for (MovingEntity i : allIndividuals) {
			i.paint(pen);
		}
	}

	/**
	 * Called by each step of timer, multiple times per second.
	 * 
	 * This should update the state of the animated shapes by just a little so
	 * they appear to move over time.
	 */
	public void update() {
		myEnvironment.update();
	}

	/**
	 * Returns a random value between min and max, inclusive
	 * 
	 * @param min  minimum possible value
	 * @param max  maximum possible value
	 */
	public int nextIntInRange(int min, int max) {
		return myGenerator.nextInt(max - min + 1) + min;
	}

	/**
	 * Returns a random value between min and max, inclusive that is guaranteed
	 * not to be zero
	 * 
	 * @param min  minimum possible value
	 * @param max  maximum possible value
	 */
	public int nextNonZeroIntInRange(int min, int max) {
		int result = 0;
		while (result == 0) {
			result = nextIntInRange(min, max);
		}
		return result;
	}
}
